package cn.bellychang.ood.litejunit.v3.framework.runners;

import cn.bellychang.ood.litejunit.v3.framework.annotation.AfterClass;
import cn.bellychang.ood.litejunit.v3.framework.annotation.BeforeClass;
import cn.bellychang.ood.litejunit.v3.framework.notification.Failure;
import cn.bellychang.ood.litejunit.v3.framework.notification.RunNotifier;
import cn.bellychang.ood.litejunit.v3.framework.runner.Description;
import cn.bellychang.ood.litejunit.v3.framework.runner.Runner;

/**
 * @author ChangLiang
 * @date 2020/5/27
 */
public class TestClassRunner extends Runner {

    protected final Runner enclosedRunner;

    private final Class<?> testClass;

    public TestClassRunner(Class<?> klass) throws InitializationError {
        this(klass, new TestClassMethodsRunner(klass));
    }

    public TestClassRunner(Class<?> klass, Runner runner) throws InitializationError {
        testClass= klass;
        enclosedRunner= runner;
    }

    @Override
    public Description getDescription() {
        return enclosedRunner.getDescription();
    }

    @Override
    public void run(RunNotifier notifier) {
        BeforeAndAfterRunner runner = new BeforeAndAfterRunner(
                getTestClass(),
                BeforeClass.class,
                AfterClass.class,
                null
        ) {
            @Override
            protected void runUnprotected() {
                enclosedRunner.run(notifier);
            }

            @Override
            protected void addFailure(Throwable targetException) {
                notifier.fireTestFailure(new Failure(getDescription(), targetException));
            }
        };

        runner.runProtected();
    }

    protected Class<?> getTestClass() {
        return testClass;
    }
}
